"""
Case Type   : 系统内部使用工具
Case Name   : 执行gs_preinstall命令，不设置参数--non-interactive
Create At   : 2021/12/13
Owner       : opentestcase012
Description :
    1.拷贝script文件,创建数据库相关文件夹
    2.配置xml文件
    3.创建初始用户并修改文件属组
    4.在script目录下，执行gs_preinstall命令：
    ./gs_preinstall -U [自定义初始用户] -G [自定义初始用户组] -X [xml配置文件路径]
    --sep-env-file=[env文件路径]  --skip-hostname-set
    5.清理环境
    删除数据库相关目录：
    rm -rf [数据库相关目录]
Expect      :
    1.创建成功
    2.配置成功
    3.成功
    4.预安装成功,需要输入密码
    5.清理成功
History     :
    modified by opentestcase012 at 2022-3-10:优化用例和teardown，避免在没卸载数据库时清理数据库失败
    modified by opentestcase039 at 2022-3-12:优化用例,预安装时建立root互信,修改获取用户信息为创建新用户，
    增加删除用户清理环境，预安装根据代码变更增加密码交互
    modified by opentestcase012 at 2022-3-17:优化用例,安装包路径取原数据库script路径,使用新建用户
    modified by opentestcase012 at 2022-9-15:优化用例,增加预安装超时时间
    modified by opentestcase012 at 2022-9-26:优化用例,增加预安装超时时间
    modified by opentestcase012 at 2023-3-24:添加步骤解压openGauss-Package-*.tar.gz,
    避免原数据库的pkg路径中无相关tar包
"""
import os
import unittest

from testcase.utils.Common import Common
from testcase.utils.Common import CommonSH
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro

Primary_SH = CommonSH('PrimaryDbUser')


@unittest.skipIf(1 == Primary_SH.get_node_num(), '单机环境不执行')
class Tools(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        self.root_node = Node('Standby2Root')
        self.node = Node('Standby2DbUser')
        self.standby1_root_node = Node('Standby1Root')
        self.standby1_node = Node('Standby1DbUser')
        self.constant = Constant()
        self.common = Common()
        self.u_name = 'gs_preinstall_0011'
        path = macro.DB_INSTANCE_PATH
        for i in range(len(path.split('/')) - 2):
            path = os.path.join(path, '..')
        self.openGauss_path = os.path.join(path, 'dir_gs_preinstall_0011')
        self.conf_path = os.path.join(self.openGauss_path, 'config')
        self.data_path = os.path.join(self.openGauss_path, 'cluster')
        self.pkg_path = os.path.join(self.openGauss_path, os.path.basename(
            os.path.dirname(macro.DB_SCRIPT_PATH)))
        self.xml_path = os.path.join(self.conf_path, 'primary_standby.xml')
        self.env_path = os.path.join(self.conf_path, 'env')

    def test_standby(self):
        text = '-----step1:拷贝script文件,创建数据库相关文件夹 expect:成功-----'
        self.log.info(text)
        pkg_path = os.path.dirname(macro.DB_SCRIPT_PATH)
        mkdir_cmd = f"rm -rf {self.openGauss_path}/;" \
            f"mkdir -p {self.conf_path};" \
            f"cp -r {pkg_path} {self.openGauss_path};" \
            f"cd {self.pkg_path};" \
            f"tar -zxf openGauss-Package-*.tar.gz;" \
            f"ls {self.pkg_path};"
        self.log.info(mkdir_cmd)
        msg = self.common.get_sh_result(self.root_node, mkdir_cmd)
        self.assertIn('64.tar.bz2', msg, '执行失败:' + text)
        script_path = os.path.join(self.pkg_path, 'script')

        test = '-----查看主机名-----'
        self.log.info(test)
        pri_node_name = self.root_node.sh("uname -n").result()
        self.log.info(pri_node_name)
        self.assertIsNotNone(pri_node_name, '执行失败:' + text)
        sta_node_name = self.standby1_root_node.sh("uname -n").result()
        self.log.info(sta_node_name)
        self.assertIsNotNone(sta_node_name, '执行失败:' + text)

        test = '-----查询系统未使用端口-----'
        self.log.info(test)
        port = self.common.get_not_used_port(self.node)
        self.assertNotEqual(0, port, '执行失败:' + text)

        text = '-----step2:配置xml文件 expect:配置成功-----'
        self.log.info(text)
        gaussdb_app_path = os.path.join(self.data_path, 'app')
        gaussdb_log_path = os.path.join(self.data_path, 'gaussdb_log')
        tmpmppdb_path = os.path.join(self.data_path, 'tmp')
        gaussdb_tool_path = os.path.join(self.data_path, 'tool')
        data_node1 = os.path.join(self.data_path, 'dn1')
        self.common.scp_file(self.root_node, 'primary_standby.xml',
                             self.conf_path)
        xml_cmd = f"sed -i 's#v_nodeNames#{pri_node_name},{sta_node_name}" \
            f"#g' {self.xml_path};" \
            f"sed -i 's#v_gaussdbAppPath#{gaussdb_app_path}#g' " \
            f"{self.xml_path};" \
            f"sed -i 's#v_gaussdbLogPath#{gaussdb_log_path}#g' " \
            f"{self.xml_path};" \
            f"sed -i 's#v_tmpMppdbPath#{tmpmppdb_path}#g' " \
            f"{self.xml_path};" \
            f"sed -i 's#v_gaussdbToolPath#{gaussdb_tool_path}#g' " \
            f"{self.xml_path};" \
            f"sed -i 's#v_corePath#{macro.DB_CORE_PATH}#g' " \
            f"{self.xml_path};" \
            f"sed -i 's#v_db_host#{self.node.db_host}," \
            f"{self.standby1_node.db_host}#g' {self.xml_path};" \
            f"sed -i 's#v_pri_nodeNames#{pri_node_name}#g' " \
            f"{self.xml_path};" \
            f"sed -i 's#v_pri_db_host#{self.node.db_host}#g' " \
            f"{self.xml_path};" \
            f"sed -i 's#v_dataPortBase#{port}#g' {self.xml_path};" \
            f"sed -i 's#v_dataNode1#{data_node1},{sta_node_name}," \
            f"{data_node1}#g' {self.xml_path};" \
            f"sed -i 's#v_sta_nodeNames#{sta_node_name}#g' " \
            f"{self.xml_path};" \
            f"sed -i 's#v_sta_db_host#{self.standby1_node.db_host}#g' " \
            f"{self.xml_path};" \
            f"cat {self.xml_path}"
        self.log.info(xml_cmd)
        result = self.root_node.sh(xml_cmd).result()
        self.log.info(result)
        msg_list = [pri_node_name, self.node.db_host,
                    sta_node_name, self.standby1_node.db_host,
                    self.data_path, f"{port}"]
        for content in msg_list:
            self.assertTrue(result.find(content) > -1, '执行失败:' + text)

        text = '-----删除用户进程 expect:成功-----'
        self.log.info(text)
        kill_cmd = f"ps -u {self.u_name} | grep -v PID| " \
            f"awk \'{{{{print $1}}}}\' | xargs kill -9"
        self.common.get_sh_result(self.root_node, kill_cmd)

        text = '-----step3:创建初始新用户并修改属组 expect:成功-----'
        self.log.info(text)
        self.common.create_user(self.root_node, self.u_name)
        file_own = f'chown -R {self.u_name}:{self.u_name} ' \
            f'{self.openGauss_path};'
        self.log.info(file_own)
        file_msg = self.root_node.sh(file_own).result()
        self.log.info(file_msg)
        self.assertEqual('', file_msg, '执行失败:' + text)

        text = '-----step4:在script目录下，执行gs_preinstall命令 ' \
               'expect:预安装成功,需要输入密码-----'
        self.log.info(text)
        preinstall_cmd = f'./gs_preinstall ' \
            f'-U {self.u_name} -G {self.u_name} -X {self.xml_path}' \
            f' --sep-env-file={self.env_path} --skip-hostname-set '
        execute_cmd = f'''cd {script_path}
                   expect <<EOF
                   set timeout 500
                   spawn {preinstall_cmd}
                   expect "you want to create trust for root (yes/no)?"
                   send "yes\\n"
                   expect "Password:"
                   send "{self.root_node.ssh_password}\\n"
                   expect "and create trust for it (yes/no)?"
                   send "yes\\n"
                   expect "Password:"
                   send "{macro.COMMON_PASSWD}\\n"
                   expect "Password:"
                   send "{macro.COMMON_PASSWD}\\n"
                   expect "Password:"
                   send "{macro.COMMON_PASSWD}\\n"
                   expect eof\n''' + '''EOF'''
        self.log.info(execute_cmd)
        msg = self.root_node.sh(execute_cmd).result()
        self.log.info(msg)
        self.assertIn(self.constant.preinstall_success_msg, msg,
                      '执行失败:' + text)

    def tearDown(self):
        self.log.info('-----step5:清理环境-----')
        text_1 = '-----删除用户下进程 expect:成功-----'
        self.log.info(text_1)
        kill_cmd = f"ps -u {self.u_name} | grep -v PID| " \
            f"awk \'{{{{print $1}}}}\' | xargs kill -9"
        self.common.get_sh_result(self.standby1_root_node, kill_cmd)
        self.common.get_sh_result(self.root_node, kill_cmd)

        text_1 = '-----删除用户 expect:成功-----'
        self.log.info(text_1)
        udel_cmd = f'userdel -r {self.u_name};'
        udel_msg1 = self.common.get_sh_result(self.standby1_root_node,
                                              udel_cmd)
        udel_msg2 = self.common.get_sh_result(self.root_node, udel_cmd)

        text_2 = '-----删除数据准备目录 expect:成功-----'
        self.log.info(text_2)
        del_cmd = f'rm -rf {self.openGauss_path}'
        self.common.get_sh_result(self.standby1_root_node, del_cmd)
        self.common.get_sh_result(self.root_node, del_cmd)
        check_cmd = f'if [ -d {self.openGauss_path} ]; ' \
            f'then echo "exists"; else echo "not exists"; fi'
        del_msg1 = self.common.get_sh_result(self.standby1_root_node,
                                             check_cmd)
        del_msg2 = self.common.get_sh_result(self.root_node, check_cmd)

        self.assertEqual('', udel_msg1 and udel_msg2, '执行失败:' + text_1)
        self.assertEqual('not exists', del_msg1 and del_msg2,
                         '执行失败:' + text_2)
        self.log.info(f'-----{os.path.basename(__file__)} end-----')
